home *** CD-ROM | disk | FTP | other *** search
/ Inter.Net 55-1 / Inter.Net 55-1.iso / CBuilder / Setup / BCB / data.z / locimpl.h < prev    next >
Encoding:
C/C++ Source or Header  |  1998-02-09  |  16.3 KB  |  473 lines

  1. #ifndef __STD_RW_LOCIMPL__
  2. #define __STD_RW_LOCIMPL__
  3. #pragma option push -b -a4 -Vx- -Ve- -w-inl -w-aus -w-sig
  4.  
  5. /***************************************************************************
  6.  *
  7.  * rw/locimpl - Declarations for the Standard Library locale private
  8.  *              implementation classes.
  9.  *
  10.  * $Id: locimpl,v 1.26 1996/10/22 05:12:47 delaney Exp $
  11.  *
  12.  ***************************************************************************
  13.  *
  14.  * (c) Copyright 1994, 1995 Rogue Wave Software, Inc.
  15.  * ALL RIGHTS RESERVED *
  16.  * The software and information contained herein are proprietary to, and
  17.  * comprise valuable trade secrets of, Rogue Wave Software, Inc., which
  18.  * intends to preserve as trade secrets such software and information.
  19.  * This software is furnished pursuant to a written license agreement and
  20.  * may be used, copied, transmitted, and stored only in accordance with
  21.  * the terms of such license and with the inclusion of the above copyright
  22.  * notice.  This software and information or any other copies thereof may
  23.  * not be provided or otherwise made available to any other person.
  24.  *
  25.  * Notwithstanding any other lease or license that may pertain to, or
  26.  * accompany the delivery of, this computer software and information, the
  27.  * rights of the Government regarding its use, reproduction and disclosure
  28.  * are as set forth in Section 52.227-19 of the FARS Computer
  29.  * Software-Restricted Rights clause.
  30.  *
  31.  * Use, duplication, or disclosure by the Government is subject to
  32.  * restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
  33.  * Technical Data and Computer Software clause at DFARS 252.227-7013.
  34.  * Contractor/Manufacturer is Rogue Wave Software, Inc.,
  35.  * P.O. Box 2328, Corvallis, Oregon 97339.
  36.  *
  37.  * This computer software and information is distributed with "restricted
  38.  * rights."  Use, duplication or disclosure is subject to restrictions as
  39.  * set forth in NASA FAR SUP 18-52.227-79 (April 1985) "Commercial
  40.  * Computer Software-Restricted Rights (April 1985)."  If the Clause at
  41.  * 18-52.227-74 "Rights in Data General" is specified in the contract,
  42.  * then the "Alternate III" clause applies.
  43.  *
  44.  **************************************************************************/
  45.  
  46.  
  47. #include <stdcomp.h>
  48.  
  49. // Macros for declaring and referencing implementation type and object names in
  50. // our private implementation namespace, or with our private prefix __rw_ stuck
  51. // on the fronts of the names if namespaces are not supported by the compiler.
  52. // The DECL version is for use inside the implementation namespace, the NAME
  53. // version for refering to the names from elsewhere.  Move to stdcomp.h?
  54.  
  55. // Macro for declaring all the has_facet and use_facet functions to be friends.
  56.  
  57. #ifndef _RWSTD_NO_FRIEND_TEMPLATES
  58. #ifndef _RWSTD_NO_NAMESPACE
  59. #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
  60. #define _RWSTD_FRIEND_USE_HAS_FACET                                     \
  61.   template <class Facet> friend                                         \
  62.       inline const Facet& std::use_facet (const locale&);                    \
  63.   template <class Facet> friend                                         \
  64.       inline bool std::has_facet (const locale&) _RWSTD_THROW_SPEC_NULL;
  65. #else
  66. #define _RWSTD_FRIEND_USE_HAS_FACET                                     \
  67.   template <class Facet> friend                                         \
  68.     inline const Facet& std::use_facet (const locale&,Facet*);               \
  69.   template <class Facet> friend                                         \
  70.     inline bool std::has_facet (const locale&,Facet*) _RWSTD_THROW_SPEC_NULL;
  71. #endif
  72. #else 
  73. #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
  74. #define _RWSTD_FRIEND_USE_HAS_FACET                                     \
  75.   template <class Facet> friend                                         \
  76.       inline const Facet& use_facet (const locale&);                    \
  77.   template <class Facet> friend                                         \
  78.       inline bool has_facet (const locale&) _RWSTD_THROW_SPEC_NULL;
  79. #else
  80. #define _RWSTD_FRIEND_USE_HAS_FACET                                     \
  81.   template <class Facet> friend                                         \
  82.     inline const Facet& use_facet (const locale&,Facet*);               \
  83.   template <class Facet> friend                                         \
  84.     inline bool has_facet (const locale&,Facet*) _RWSTD_THROW_SPEC_NULL;
  85. #endif // _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
  86. #endif// _RWSTD_NO_NAMESPACE
  87. #else
  88. #define _RWSTD_FRIEND_USE_HAS_FACET public:
  89. #endif
  90.  
  91. #ifndef _RWSTD_NO_NAMESPACE
  92. namespace __rwstd {
  93. using namespace std;
  94. #endif
  95.  
  96. // Implementation class template -- timepunct<charT>
  97. //
  98. // A facet such as this should have been included in the standard.  We just
  99. // declare it here; the definition occurs below, after locale::facet has been
  100. // defined.
  101.  
  102. template <class charT> class timepunct;
  103.  
  104. // Implementation forward declarations:
  105.  
  106. class _RWSTDExport locale_imp;
  107. class _RWSTDExport facet_imp;
  108.  
  109. class _RWSTDExport digit_map_base;
  110. template <class charT> class _RWSTDExportTemplate digit_map;
  111. template <class charT> class _RWSTDExportTemplate keyword_def;
  112. template <class charT> class _RWSTDExportTemplate keyword_map;
  113. template <class charT> class _RWSTDExportTemplate keyword_cracker;
  114.  
  115. class _RWSTDExport digit_reader_base;
  116. template <class charT> class digit_reader_base_1;
  117. template <class charT,class InputIterator>
  118.   class _RWSTDExportTemplate digit_reader;
  119.  
  120. class _RWSTDExport digit_writer_base;
  121. template <class charT>
  122.   class _RWSTDExportTemplate digit_writer_base_1;
  123. template <class charT,class OutputIterator>
  124.   class _RWSTDExportTemplate digit_writer;
  125.  
  126. // ------------------------------------
  127. // Implementation class -- ref_counted.
  128. // ------------------------------------
  129.  
  130. // Common base class for reference-counted classes.  Currently used only by
  131. // locale_imp and facet_imp, but could be used more generally.
  132.  
  133. class _RWSTDExport ref_counted {
  134.   friend class _STD::locale;
  135.  
  136.   size_t ref_count_;
  137.   #ifdef _RWSTD_MULTI_THREAD
  138.   _RWSTDMutex mutex_;
  139.   #endif
  140.  
  141.  protected:
  142.   ref_counted (size_t initial_refs):
  143.       ref_count_(initial_refs) { }
  144.  
  145.   // Ensure derived class destructors are always virtual.
  146.   virtual ~ref_counted (void);
  147.  
  148.   // Does protected access make these accessible to friends of derived classes?
  149.   // We're about to find out ...
  150.  
  151.   static void add_reference (ref_counted *ob) {
  152.     STDGUARD(ob->mutex_);
  153.     ++ob->ref_count_;
  154.   }
  155.  
  156.   static void remove_reference (ref_counted *ob) {
  157.     size_t refs;
  158.     {
  159.       STDGUARD(ob->mutex_);
  160.       refs=--ob->ref_count_;
  161.     }
  162.     if (!refs)
  163.       delete ob;
  164.   }
  165.  
  166.   static void add_possible_reference (ref_counted *ob) {
  167.     if (ob)
  168.       add_reference(ob);
  169.   }
  170.  
  171.   static void remove_possible_reference (ref_counted *ob) {
  172.     if (ob)
  173.       remove_reference(ob);
  174.   }
  175. };
  176.  
  177. // We would prefer to define locale::id and locale::facet entirely as nested
  178. // classes of locale, but current compilers have problems with out-of-line
  179. // definition of members of such classes, so we have to derive most of their
  180. // behavior from unnested implementation classes:
  181.  
  182. // --------------------------------------
  183. // Implementation class -- locale_id_imp.
  184. // --------------------------------------
  185.  
  186. class _RWSTDExport locale_id_imp {
  187.  protected:
  188.   _MUTABLE size_t id_;
  189.   static size_t last_used_id_;
  190.   void init() const;
  191.  public:
  192.   locale_id_imp () : id_ (0) {}  // __BORLANDC__
  193.  
  194. };
  195.  
  196. // ----------------------------------
  197. // Implementation class -- facet_imp.
  198. // ----------------------------------
  199.  
  200. class _RWSTDExport facet_imp: public ref_counted
  201. {
  202.   _RWSTD_FRIEND_USE_HAS_FACET
  203.   friend class locale_imp;
  204.   friend class _STD::locale;
  205.  
  206.   enum {
  207.     facet_cat_ = 0,
  208.     ok_implicit_ = 0,
  209.     init_done  = 0x0001
  210.   };
  211.  
  212.  private:
  213.   int flags_;
  214.   int category_;     // Should be same type as locale::category
  215.  
  216.  protected:
  217.   facet_imp (size_t refs, int cat=0):
  218.       ref_counted(refs), flags_(0), category_(cat) { }
  219.  
  220.   // rw_init() is called by locale::install the first time a facet is installed
  221.   // in its first locale.  Some facets override it to set up private data that
  222.   // depends on return values of virtual do_xxx functions that can't be called
  223.   // in the constructor.
  224.   virtual void rw_init (void) { }
  225. };
  226.  
  227.  
  228. #ifndef _RWSTD_NO_NAMESPACE
  229. }
  230. #endif
  231.  
  232. #include "rw/locvecto.h"
  233.  
  234. #ifndef _RWSTD_NO_NAMESPACE
  235. namespace __rwstd {
  236. #endif
  237.  
  238. // -----------------------------------
  239. // Implementation class -- locale_imp.
  240. // -----------------------------------
  241.  
  242. class _RWSTDExport locale_imp: public ref_counted
  243. {
  244.   _RWSTD_FRIEND_USE_HAS_FACET
  245.   friend class _STD::locale;
  246.  
  247.   // Same type as locale::category ...
  248.   typedef int locale_category;
  249.   locale_vector<string> names_;
  250.   locale_vector<facet_imp*> vec_;
  251.  
  252.   locale_category native_cats_;
  253.   locale_category named_cats_;
  254.   string big_name_;
  255.   bool named_;
  256.  
  257.   locale_imp (size_t sz=36, size_t refs=0);
  258.   locale_imp (const locale_imp&,size_t refs);
  259.   ~locale_imp ();
  260.  
  261. #ifdef _MSC_VER
  262.  public:
  263. #endif
  264.   inline facet_imp *get_facet (size_t i) const
  265.     { return i<vec_.size()? vec_[i] : NULL; }
  266. #ifdef _MSC_VER
  267.  private:
  268. #endif
  269.  
  270.   const char *category_name (locale_category) const;
  271.  
  272.   // Map C library LC_xxx constants into facet categories.
  273.   static locale_category map_category (locale_category);
  274.  
  275.   // Parse a locale name into category names.
  276.   static bool parse_name (locale_vector<string>&,const char*);
  277.   // Combine category names to create a locale name.
  278.   static bool build_name (string&,const locale_vector<string>&);
  279. };
  280.  
  281. // ---------------------------------------
  282. // Implementation class -- digit_map_base.
  283. // ---------------------------------------
  284.  
  285. // A place to stash some static constants, so that each instantiation of the
  286. // derived class rwstd::digit_map does not have to have a separate copy.
  287.  
  288. struct _RWSTDExport digit_map_base {
  289.   enum { zero, minus, plus, X, x, E, e };
  290.   static const char punct_chars[7];   // "0-+XxEe"
  291.   static const char digit_chars[22];  // "0123456789ABCDEFabcdef"
  292.   static const char char_values[22];  // Corresponding values in range 0-15
  293. };
  294.  
  295. // --------------------------------------------------
  296. // Implementation class template -- digit_map<charT>.
  297. // --------------------------------------------------
  298.  
  299. // Maps digits into their corresponding numeric values, and caches widened
  300. // equivalents of some number-related punctuation characters that don't depend
  301. // on the numpunct facet.  A private instance of this class is hidden in
  302. // ctype<charT> for use by numeric conversion facets.  A call to init must
  303. // precede the first call to eval if is_inited() is false.  Eval returns 0-15
  304. // if argument is a valid digit, a negative value otherwise.
  305. //
  306. // Specialized for char for performance.  The specialization assumes digits
  307. // fit into the char code-set in an ASCII-like manner ('0'..'9' contiguous,
  308. // 'A'..'F' contiguous, 'a'..'f' contiguous, '0' < 'A' < 'a').
  309.  
  310. template <class charT>
  311. class _RWSTDExportTemplate digit_map:
  312.     public digit_map_base
  313. {
  314.   bool inited;
  315.   charT punct_array[7];
  316.   charT digit_array[22];
  317.   char value_array[22];
  318.  public:
  319.   typedef charT char_type;
  320.  
  321.   digit_map (void): inited(false) { }
  322.   bool is_inited (void) const { return inited; }
  323.   void init (const ctype<charT>& ct);
  324.   const charT *get_punct (void) const { return punct_array; }
  325.   int eval (charT) const;
  326.  
  327.   // Can-opener for getting the digit_map out of a ctype.  (Works because of
  328.   // the friend declaration in ctype_helper<charT> below.)
  329.   static inline const digit_map<charT>&
  330.       get_digit_map (const ctype<charT>&);
  331. };
  332.  
  333. _RWSTD_TEMPLATE
  334. class _RWSTDExportTemplate digit_map<char>:
  335.     public digit_map_base
  336. {
  337.  public:
  338.   typedef char char_type;
  339.  
  340.   bool is_inited (void) const { return true; }
  341.   const char *get_punct (void) const { return punct_chars; }
  342.   inline int eval (char c) const;
  343.   static inline const digit_map<char>&
  344.       get_digit_map (const ctype<char>&);
  345.  
  346.  private:
  347.   // These declarations stop BC5 from firing the template for member function
  348.   // digit_map<charT>::init on char, then complaining that init and inited are
  349.   // not members of digit_map<char>.
  350.   void init (const ctype<char>&);
  351.   bool inited;
  352. };
  353.  
  354. // ----------------------------------------------------
  355. // Implementation class template -- keyword_def<charT>.
  356. // ----------------------------------------------------
  357.  
  358. // Helper class used in parsing keywords from input (such as true/false in
  359. // num_get, month and day names in time_get, etc).
  360.  
  361. template <class charT>
  362. class _RWSTDExportTemplate keyword_def {
  363.  public:
  364.   const charT *s;
  365.   int v;
  366. };
  367.  
  368. // ----------------------------------------------------
  369. // Implementation class template -- keyword_map<charT>.
  370. // ----------------------------------------------------
  371.  
  372. // Defines a set of keywords to be recognized on input and to be written to
  373. // output.  Private instances are hidden in numpunct (for true/false) and
  374. // rwstd::timepunct (for month and weekday names).
  375.  
  376. template <class charT>
  377. class _RWSTDExportTemplate keyword_map {
  378.  public:
  379.   int num_defs_;
  380.   const keyword_def<charT> *defs_;
  381. };
  382.  
  383.  
  384.  
  385. // ---------------------------------------------------
  386. // Implementation class template -- punct_data<charT>.
  387. // ---------------------------------------------------
  388.  
  389. // Common base class for rwstd::numpunct_data and rwstd::moneypunct_data.
  390.  
  391. template <class charT>
  392. class _RWSTDExportTemplate punct_data {
  393.   friend class digit_reader_base_1<charT>;
  394.   friend class digit_writer_base_1<charT>;
  395.  public:
  396.   typedef basic_string<charT,char_traits<charT>,allocator<charT> > string_type;
  397.  protected:
  398.   charT dp_, ts_;
  399.   string gr_;
  400. };
  401.  
  402.  
  403. // ------------------------------------------------------
  404. // Implementation function templates -- create_xxx_facet.
  405. // ------------------------------------------------------
  406.  
  407. // The facet_maker<Facet>::maker_func functions described above delegate the
  408. // actual construction of facets to three inline function templates named
  409. // create_xxx_facet, where xxx is 'classic' or 'native' or 'named'.  The
  410. // default (template) versions of these functions construct facets as follows:
  411. //
  412. //   classic -- default constructor for the facet with only the refs argument.
  413. //   native -- calls create_named_facet with a name of "".
  414. //   named -- calls create_classic_facet, ignoring the passed name.
  415. //
  416. // This default behavior is overridden (specialized) for certain facet types.
  417. // In particular, create_named_facet is specialized for all facet types that
  418. // have a derived _byname version, to construct that version with the passed
  419. // name (see <rw/rwlocale>) and create_native_facet is specialized for all
  420. // facet types whose "native" behavior (as determined by the vendor) differs
  421. // from the byname facet with a name of "" (see <rw/vendor>).
  422.  
  423. template <class Facet>
  424. inline Facet*  _RWSTDExportTemplate create_named_facet
  425.     (Facet*,const char*,size_t refs);
  426.  
  427. template <class Facet>
  428. inline Facet*  _RWSTDExportTemplate create_native_facet (Facet*);
  429.  
  430. template <class Facet>
  431. inline Facet* _RWSTDExportTemplate create_classic_facet (Facet*)
  432. {
  433.  return new Facet(1);
  434. }
  435.  
  436.  
  437. // ----------------------------------------------------
  438. // Implementation class template -- facet_maker<Facet>.
  439. // ----------------------------------------------------
  440.  
  441. // When use_facet (inline) finds that a locale does not contain an _EXPLICIT
  442. // facet of the requested type, it calls locale::make__EXPLICIT (non-template)
  443. // to create or find the facet in a cache, and install it in the locale.  As a
  444. // parameter to make__EXPLICIT, use_facet passes a call-back function which
  445. // make__EXPLICIT can call to construct a facet of the requested type if needed.
  446. // The call-back functions are obtained by instantiating the following helper
  447. // class template:
  448.  
  449. template <class Facet>
  450. class _RWSTDExportTemplate facet_maker {
  451.  public:
  452.   static facet_imp *maker_func (int t, const char* name, size_t refs)
  453.   {
  454.     if (t==0)
  455.       return create_classic_facet ((Facet*)0);
  456.     else if (t==1)
  457.       return create_native_facet ((Facet*)0);
  458.     else
  459.       return create_named_facet ((Facet*)0,name,refs);
  460.   }
  461. };
  462.  
  463. #ifndef _RWSTD_NO_NAMESPACE
  464. } // namespace __rwstd
  465. #endif
  466.  
  467. #ifdef _RWSTD_COMPILE_INSTANTIATE
  468. #include <rw/locimpl.cc>
  469. #endif
  470.  
  471. #pragma option pop
  472. #endif // __STD_RW_LOCIMPL__
  473.